import { _decorator, Component, Node, Sprite, SpriteFrame, Button, Label, AudioSource, Vec3, tween, randomRangeInt, UIOpacity, Quat } from 'cc';
import { WsMgr } from '../../TCP/WsMgr';
import AudioMgr from '../../Common/AudioMgr';
const { ccclass, property } = _decorator;

/**
 * 骰子数据接口定义
 */
interface DiceData {
    node: Node;
    value: number;
    sprite: Sprite | null;
    uiOpacity: UIOpacity | null;
}

/**
 * Cocos 3.8.1骰钟游戏主控制器（开盖即显示骰子版）
 * 骰子在开盖时已经显示好，开盖立即可以看到
 */
@ccclass('DiceCupController')
export class DiceCupController extends Component {
    /** 骰钟容器节点 */
    @property({ type: Node, tooltip: "骰钟容器节点" })
    cupNode: Node = null!;

    /** 骰钟盖子节点 - 用于开盖动画 */
    @property({ type: Node, tooltip: "骰钟盖子节点" })
    cupLidNode: Node = null!;

    /** 骰子节点数组（必须设置3个） */
    @property({ type: Node, tooltip: "骰子节点数组", displayName: "骰子节点(3个)" })
    diceNodes: Node[] = [];

    /** 摇晃按钮 */
    @property({ type: Button, tooltip: "摇晃按钮" })
    shakeButton: Button = null!;

    /** 摇晃按钮的UIOpacity组件 */
    private shakeButtonUiOpacity: UIOpacity | null = null;

    /** 结果显示标签 */
    @property({ type: Label, tooltip: "结果显示标签" })
    resultLabel: Label = null!;

    /** 结果标签的UIOpacity组件 */
    private resultUiOpacity: UIOpacity | null = null;

    /** 总分显示标签 */
    @property({ type: Label, tooltip: "总分显示标签" })
    totalScoreLabel: Label = null!;

    /** 当局得分动画节点 */
    @property({ type: Node, tooltip: "当局得分动画节点" })
    currentScoreNode: Node = null!;

    /** 当局得分标签 */
    @property({ type: Label, tooltip: "当局得分标签" })
    currentScoreLabel: Label = null!;

    /** 额外得分动画节点 */
    @property({ type: Node, tooltip: "额外得分动画节点（三个相同点数时显示）" })
    bonusScoreNode: Node = null!;

    /** 额外得分标签 */
    @property({ type: Label, tooltip: "额外得分标签" })
    bonusScoreLabel: Label = null!;

    /** 骰子精灵帧（0-5对应1-6点） */
    @property({ type: [SpriteFrame], tooltip: "骰子精灵帧(0-5对应1-6点)" })
    diceSprites: SpriteFrame[] = [];
  
    /** 得分音效 */
    @property({ type: AudioSource, tooltip: "得分音效" })
    scoreAudio: AudioSource = null!;

    /** 额外得分音效 */
    @property({ type: AudioSource, tooltip: "额外得分音效" })
    bonusAudio: AudioSource = null!;

    /** 骰子数据数组 */
    private diceDataArray: DiceData[] = [];

    /** 是否正在摇晃状态 */
    private isShaking: boolean = false;

    /** 骰钟原始位置 */
    private originalCupPosition: Vec3 = Vec3.ZERO;

    /** 盖子原始位置 */
    private originalLidPosition: Vec3 = Vec3.ZERO;

    /** 盖子原始旋转 */
    private originalLidRotation: Quat = Quat.IDENTITY;

    /** 盖子打开位置 */
    private lidOpenPosition: Vec3 = new Vec3();
    
    /** 盖子打开旋转 */
    private lidOpenRotation: Quat = new Quat();

    /** 当前总分 */
    private totalScore: number = 0;

    /** 当局得分 */
    private currentRoundScore: number = 0;

    /** 额外得分 */
    private bonusScore: number = 0;

    /** 是否开出三个相同点数 */
    private isThreeOfAKind: boolean = false;

    /** 是否正在播放得分动画 */
    private isPlayingScoreAnimation: boolean = false;

    /** 当前动画的tween实例 */
    private currentTweens: any[] = [];

    /** 当前数字滚动动画的定时器 */
    private scoreAnimationTimer=null;

    /** 额外得分动画的定时器 */
    private bonusAnimationTimer= null;

    /**
     * 组件加载时初始化
     */
    protected onLoad(): void {
        this.validateComponents();
        this.initializeDiceData();
        this.setupResultLabelOpacity();
        this.setupShakeButtonOpacity();
        this.setupEventListeners();
        this.originalCupPosition = this.cupNode.position.clone();
        this.originalLidPosition = this.cupLidNode.position.clone();
        this.originalLidRotation = this.cupLidNode.rotation.clone();
        
        // 计算盖子打开状态的位置和旋转
        this.calculateLidOpenState();
        
        this.hideResult();
        this.hideCurrentScore();
        this.hideBonusScore();
        this.closeCupLid(true); // 初始关闭盖子
        // 初始化分数显示
        this.updateTotalScoreDisplay();
    }
    private audioSrc:AudioMgr;

    initAudioMgr(audioSrc:AudioMgr ){
    this.audioSrc=audioSrc;
    }
    /** 播放音效 */
    private playEffectMisic(adoName: string): void {
    let audioName = this.audioSrc.getAudioName(adoName);
    this.audioSrc.onPlayOneShot(audioName);
   }

    /**
     * 计算盖子打开状态的位置和旋转
     */
    private calculateLidOpenState(): void {
        // 开盖状态：向右提（x+125）向上提（Y+70）并向右旋转（Z轴-50度）
        Vec3.add(this.lidOpenPosition, this.originalLidPosition, new Vec3(125, 70, 0));
        Quat.fromEuler(this.lidOpenRotation, 0, 0, -50);
    }

    /**
     * 验证必要组件是否已正确设置
     */
    private validateComponents(): void {
        if (this.diceNodes.length !== 3) {
            console.error("错误：必须设置3个骰子节点！");
        }
        if (!this.cupLidNode) {
            console.error("错误：必须设置骰钟盖子节点！");
        }

        // 验证骰子节点是否有必要组件
        this.diceNodes.forEach((node, index) => {
            const sprite = node.getComponent(Sprite);
            const uiOpacity = node.getComponent(UIOpacity);
            if (!sprite) {
                console.error(`错误：骰子节点${index}缺少Sprite组件！`);
            }
            if (!uiOpacity) {
                console.error(`错误：骰子节点${index}缺少UIOpacity组件！`);
            }
        });

        // 验证结果标签是否有UIOpacity组件
        const resultOpacity = this.resultLabel.node.getComponent(UIOpacity);
        if (!resultOpacity) {
            console.error("错误：结果标签节点缺少UIOpacity组件！");
        }

        // 验证摇晃按钮是否有UIOpacity组件
        const buttonOpacity = this.shakeButton.node.getComponent(UIOpacity);
        if (!buttonOpacity) {
            console.error("错误：摇晃按钮节点缺少UIOpacity组件！");
        }

        if (this.diceSprites.length !== 6) {
            console.error("错误：必须提供6个骰子精灵帧（1-6点）！");
        }

        // 验证得分相关组件
        if (!this.totalScoreLabel) {
            console.error("错误：必须设置总分显示标签！");
        }
        if (!this.currentScoreNode) {
            console.error("错误：必须设置当局得分动画节点！");
        }
        if (!this.currentScoreLabel) {
            console.error("错误：必须设置当局得分标签！");
        }
        if (!this.bonusScoreNode) {
            console.error("错误：必须设置额外得分动画节点！");
        }
        if (!this.bonusScoreLabel) {
            console.error("错误：必须设置额外得分标签！");
        }
    }

    /**
     * 初始化骰子数据
     */
    private initializeDiceData(): void {
        this.diceDataArray = [];
        for (let i = 0; i < 3; i++) {
            const sprite = this.diceNodes[i].getComponent(Sprite);
            const uiOpacity = this.diceNodes[i].getComponent(UIOpacity);
            this.diceDataArray.push({
                node: this.diceNodes[i],
                value: 1,
                sprite: sprite,
                uiOpacity: uiOpacity
            });
            // 初始显示1点
            if (sprite && this.diceSprites.length > 0) {
                sprite.spriteFrame = this.diceSprites[0];
            }
            // 初始隐藏骰子
            if (uiOpacity) {
                uiOpacity.opacity = 0;
            }
        }
    }

    /**
     * 设置结果标签的UIOpacity组件
     */
    private setupResultLabelOpacity(): void {
        this.resultUiOpacity = this.resultLabel.node.getComponent(UIOpacity);
    }

    /**
     * 设置摇晃按钮的UIOpacity组件
     */
    private setupShakeButtonOpacity(): void {
        this.shakeButtonUiOpacity = this.shakeButton.node.getComponent(UIOpacity);
        // 确保按钮初始状态是可见的
        if (this.shakeButtonUiOpacity) {
            this.shakeButtonUiOpacity.opacity = 255;
        }
    }

    /**
     * 设置事件监听器
     */
    private setupEventListeners(): void {
        this.shakeButton.node.on(Button.EventType.CLICK, this.onShakeButtonClicked, this);
    }

    /**
     * 隐藏结果显示 - 使用UIOpacity组件
     */
    private hideResult(): void {
        if (this.resultUiOpacity) {
            this.resultUiOpacity.opacity = 0;
        }
        this.resultLabel.node.scale = new Vec3(0.8, 0.8, 1);
    }

    /**
     * 隐藏当局得分显示
     */
    private hideCurrentScore(): void {
        this.currentScoreNode.active = false;
        this.currentScoreNode.scale = new Vec3(0.5, 0.5, 1);
        this.currentScoreNode.position = new Vec3(0, -290, 0); // 重置位置
    }

    /**
     * 隐藏额外得分显示
     */
    private hideBonusScore(): void {
        this.bonusScoreNode.active = false;
        this.bonusScoreNode.scale = new Vec3(0.5, 0.5, 1);
        this.bonusScoreNode.position = new Vec3(140, -290, 0); // 重置位置
    }

    /**
     * 关闭骰钟盖子 - 优化版本：从当前位置平滑动画到关闭位置
     * @param instant 是否立即关闭，无动画
     */
    private closeCupLid(instant: boolean = false): void {
        if (instant) {
            // 立即关闭：直接设置到原始位置
            this.cupLidNode.position = this.originalLidPosition.clone();
            this.cupLidNode.rotation = this.originalLidRotation.clone();
            return;
        }

        // 播放关盖音效
        this.playEffectMisic('close_cup');

        // 隐藏骰子 - 在关盖过程中隐藏
        this.hideDiceWithAnimation();

        // 平滑关闭盖子动画：从当前位置动画到原始位置
        const tweenInstance = tween(this.cupLidNode)
            .to(0.8, { 
                position: this.originalLidPosition.clone(),
                rotation: this.originalLidRotation.clone()
            }, { 
                easing: 'backInOut'
            })
            .call(() => {
                // 动画完成回调
                this.onLidCloseComplete();
            })
            .start();

        this.currentTweens.push(tweenInstance);
    }

    /**
     * 隐藏骰子动画（在关盖过程中调用）
     */
    private hideDiceWithAnimation(): void {
        this.diceDataArray.forEach((dice, index) => {
            if (dice.uiOpacity) {
                // 延迟逐个隐藏骰子，增加动画层次感
                setTimeout(() => {
                    const tweenInstance = tween(dice.uiOpacity!)
                        .to(0.3, { opacity: 0 }, { easing: 'sineOut' })
                        .start();
                    this.currentTweens.push(tweenInstance);
                }, index * 50);
            }
        });
    }

    /**
     * 盖子关闭完成回调
     */
    private onLidCloseComplete(): void {
       // console.log("盖子关闭完成");
    }

    /**
     * 摇晃按钮点击事件处理 - 优化版本：先关盖再摇晃
     */
    private onShakeButtonClicked(): void {
        if (this.isShaking) return;
    
        let ranking= WsMgr.getInstance().mRankingResult; 
        if (ranking.match_limit>=ranking.match_limit_config) {
            alert('You have completed the game rounds and are waiting for the event settlement.');
            return
        }
        // 【新增】如果正在播放得分动画，立即加速完成所有动画
        if (this.isPlayingScoreAnimation) {
            this.accelerateAllScoreAnimations();
            return;
        }
       
        this.isShaking = true;
        this.shakeButton.interactable = false;
        
        // 【新增】点击后渐渐隐藏开始按钮
        this.hideShakeButtonWithAnimation();
        
        this.hideResult();
        this.hideCurrentScore();
        this.hideBonusScore();
        
        // 重置三个相同点数状态
        this.isThreeOfAKind = false;
        this.bonusScore = 0;
        
        // 先关闭盖子，然后开始摇晃
        this.closeCupLid();

        // 延迟开始摇晃，等待关盖动画完成
        setTimeout(() => {
            // 播放摇晃音效
            this.playEffectMisic('yao_touzi');
            // 开始摇晃动画
            this.startShakeAnimation();
        }, 800); // 等待关盖动画完成
    }

    /**
     * 【新增】加速完成所有得分动画
     */
    private accelerateAllScoreAnimations(): void {
        // 停止所有动画
        this.stopAllAnimations();
        
        // 立即完成所有得分计算
        let finalScore = this.totalScore + this.currentRoundScore;
        if (this.isThreeOfAKind) {
            finalScore += this.bonusScore;
        }
        
        // 立即更新总分显示
        this.totalScore = finalScore;
        this.updateTotalScoreDisplay();
        
        // 立即隐藏所有得分节点
        this.currentScoreNode.active = false;
        this.bonusScoreNode.active = false;
        
        // 重置动画状态
        this.isPlayingScoreAnimation = false;
        
        // 立即开始新游戏
        this.isShaking = true;
        this.shakeButton.interactable = false;
        this.hideShakeButtonWithAnimation();
        this.hideResult();
        this.hideCurrentScore();
        this.hideBonusScore();
        this.closeCupLid();

        // 延迟开始摇晃，等待关盖动画完成
        setTimeout(() => {
            // 播放摇骰子音效
            this.playEffectMisic('yao_touzi');
            this.startShakeAnimation();
        }, 800);
    }

    /**
     * 【新增】停止所有动画
     */
    private stopAllAnimations(): void {
        // 停止所有tween动画
        this.currentTweens.forEach(tweenInstance => {
            if (tweenInstance && typeof tweenInstance.stop === 'function') {
                tweenInstance.stop();
            }
        });
        this.currentTweens = [];
        
        // 停止数字滚动动画
        if (this.scoreAnimationTimer) {
            clearTimeout(this.scoreAnimationTimer);
            this.scoreAnimationTimer = 0;
        }
        
        // 停止额外得分动画定时器
        if (this.bonusAnimationTimer) {
            clearTimeout(this.bonusAnimationTimer);
            this.bonusAnimationTimer = 0;
        }
    }

    /**
     * 【新增】渐渐隐藏摇晃按钮动画
     */
    private hideShakeButtonWithAnimation(): void {
        if (this.shakeButtonUiOpacity) {
            const tweenInstance = tween(this.shakeButtonUiOpacity)
                .to(0.5, { opacity: 0 }, { easing: 'sineOut' })
                .call(() => {
                    // 动画完成后完全隐藏按钮节点
                    this.shakeButton.node.active = false;
                })
                .start();
            this.currentTweens.push(tweenInstance);
        } else {
            // 如果没有UIOpacity组件，直接隐藏
            this.shakeButton.node.active = false;
        }
    }

    /**
     * 【新增】渐渐显示摇晃按钮动画
     */
    private showShakeButtonWithAnimation(): void {
        // 先确保按钮节点是active的
        this.shakeButton.node.active = true;
        this.shakeButton.interactable = true;
        
        if (this.shakeButtonUiOpacity) {
            // 设置初始透明度为0
            this.shakeButtonUiOpacity.opacity = 0;
            
            // 执行渐显动画
            const tweenInstance = tween(this.shakeButtonUiOpacity)
                .to(0.5, { opacity: 255 }, { easing: 'sineIn' })
                .start();
            this.currentTweens.push(tweenInstance);
        }
    }

    /**
     * 开始骰钟摇晃动画 - 上下摇晃版本
     */
    private startShakeAnimation(): void {
        // 发送开始指令
        WsMgr.getInstance().bet(0,WsMgr.getInstance().getTableType(),0); 
          
        // 重置骰子位置和状态
        this.resetDice();

        // 隐藏骰子 - 使用UIOpacity组件
        this.diceDataArray.forEach(dice => {
            if (dice.uiOpacity) {
                dice.uiOpacity.opacity = 0;
            }
        });
        // 执行骰钟上下摇晃动画
        const tweenInstance = tween(this.cupNode)
            .to(0.1, { position: new Vec3(this.originalCupPosition.x, this.originalCupPosition.y + 30, 0) })
            .repeat(7, // 增加重复次数使上下摇晃更明显
                tween()
                    .by(0.07, { position: new Vec3(0, 20, 0) }, { easing: 'sineInOut' }) // 上移
                    .by(0.07, { position: new Vec3(0, -40, 0) }, { easing: 'sineInOut' }) // 下移
                    .by(0.07, { position: new Vec3(0, 20, 0) }, { easing: 'sineInOut' }) // 回到中间
            )
            .to(0.4, { position: this.originalCupPosition })
            .call(() => this.finishShaking())
            .start();

        this.currentTweens.push(tweenInstance);
    }

    /**
     * 重置骰子位置和旋转
     */
    private resetDice(): void {
        const positions = [
            new Vec3(-50, 10, 0),  // 左骰子位置
            new Vec3(0, 33, 0),    // 中骰子位置
            new Vec3(50, 10, 0)    // 右骰子位置
        ];

        this.diceDataArray.forEach((dice, index) => {
            dice.node.position = positions[index];
            dice.node.rotation = Quat.IDENTITY;
            dice.node.scale = new Vec3(1, 1, 1);
        });
    }

    /**
     * 完成摇晃，生成结果并显示
     */
    private finishShaking(): void {
        // 执行开盖动画
        this.playLidOpenAnimation();
        
        this.isShaking = false;
    }

    /**
     * 播放开盖动画 - 核心修改：开盖时骰子已经显示好
     */
    private playLidOpenAnimation(): void {
        // 播放开盖音效
        this.playEffectMisic('open_cup');
        // 【核心修改】在开盖动画开始前就显示骰子（但不播放动画）
        this.showDiceImmediately();

        // 【新增】开盖时渐显开始按钮
        this.showShakeButtonWithAnimation();
        
        //得分动画
        this.playScoreAnimation();

        // 开盖动画：从关闭位置动画到打开位置
        const tweenInstance = tween(this.cupLidNode)
            .to(1.2, {
                position: this.lidOpenPosition.clone(),
                rotation: this.lidOpenRotation.clone()
            }, { 
                easing: 'backOut'
            })
            .call(() => {
                // 开盖完成后显示结果和得分动画
                this.showResult(); 
                
            })
            .start();

        this.currentTweens.push(tweenInstance);
    }

    /**
     * 【新增】立即显示骰子（无动画效果）
     * 骰子在开盖时就已经显示好，开盖立即可以看到
     */
    private showDiceImmediately(): void {
        this.diceDataArray.forEach((dice) => {
            if (dice.uiOpacity) {
                // 直接设置透明度为255，不播放动画
                dice.uiOpacity.opacity = 255;
            }
            // 确保骰子处于正常大小
            dice.node.scale = new Vec3(1, 1, 1);
            // 确保骰子没有旋转
            dice.node.rotation = Quat.IDENTITY;
        });
    }

    /**
     * 生成三个骰子的随机结果
     */
    public generateRandomResults(randomValueArray:number[],bonusScore:number): void {
        let total = 0;
        const values: number[] = [];
        
        this.diceDataArray.forEach((dice, index) => {
            const randomValue = randomValueArray[index]; // 1-6的随机数
            if (dice.sprite && randomValue - 1 < this.diceSprites.length) {
                dice.sprite.spriteFrame = this.diceSprites[randomValue - 1];
                dice.value = randomValue;
            }
            total += randomValue;
            values.push(randomValue);
        });
        
        // 计算当局得分
        this.currentRoundScore = total;
        // 检查是否三个点数相同
        this.checkThreeOfAKind(values,bonusScore);
    }

    /**
     * 检查是否三个点数相同
     */
    private checkThreeOfAKind(values: number[],bonusScore:number): void {
        if (values[0] === values[1] && values[1] === values[2]) {
            this.isThreeOfAKind = true;
            // 计算额外得分：基础分×2
            this.bonusScore = bonusScore;
            // 更新结果显示，添加三个相同点数的提示
            this.resultLabel.string += ` | 三个${values[0]}点！额外+${this.bonusScore}分`;
        } else {
            this.isThreeOfAKind = false;
            this.bonusScore = 0;
        }
    }

    /**
     * 播放得分动画效果
     */
    private playScoreAnimation(): void {
        this.isPlayingScoreAnimation = true;
        
        // 显示当局得分节点
        this.currentScoreNode.active = true;
        this.currentScoreNode.getChildByName('ScoreBg').active=true;
        this.currentScoreLabel.string = `+${this.currentRoundScore}`;
        
        // 播放得分音效
        if (this.scoreAudio) {
            this.scoreAudio.play();
        }

        // 当局得分动画：弹出效果
        const tweenInstance = tween(this.currentScoreNode)
            .set({ scale: new Vec3(0.5, 0.5, 1), position: new Vec3(0, -333, 0) })
            .to(0.5, { scale: new Vec3(1.2, 1.2, 1) }, { easing: 'backOut' })
            .to(0.2, { scale: new Vec3(1, 1, 1) }, { easing: 'sineOut' })
            .delay(1) // 停留1秒
            .call(() => {
                // 开始移动到总分位置的动画
                this.moveScoreToTotal();
            })
            .start();

        this.currentTweens.push(tweenInstance);

        // 【修改】如果有额外得分，同步开始额外得分动画
        if (this.isThreeOfAKind) {
            this.playBonusScoreAnimation();
             //播放大奖音效
             this.playEffectMisic('girl_bonus');
        }
    }

    /**
     * 移动当局得分到总分位置
     */
    private moveScoreToTotal(): void {
        // 计算总分标签的世界坐标位置
        const worldPos = this.totalScoreLabel.node.worldPosition;
        this.currentScoreNode.getChildByName('ScoreBg').active=false;
        // 当局得分移动到总分位置
        const tweenInstance = tween(this.currentScoreNode)
            .to(0.8, { 
                worldPosition: new Vec3(worldPos.x, worldPos.y, worldPos.z),
                scale: new Vec3(0.3, 0.3, 1)
            }, { easing: 'sineIn' })
            .call(() => {
                // 动画完成后更新总分
                this.addToTotalScore();
            })
            .start();

        this.currentTweens.push(tweenInstance);
    }

    /**
     * 将当局得分加入到总分
     */
    private addToTotalScore(): void {
        // 隐藏当局得分节点
        this.currentScoreNode.active = false;
        
        // 播放总分更新音效
        if (this.scoreAudio) {
            this.scoreAudio.play();
        }
        
        // 更新总分（先只加基础分）
        const oldTotal = this.totalScore;
        this.totalScore += this.currentRoundScore;
        
        // 总分数字滚动动画
        this.animateTotalScore(oldTotal, this.totalScore, () => {
            // 基础分动画完成后，如果有额外得分，立即开始额外分数更新
            if (this.isThreeOfAKind) {
                this.addBonusToTotalScore();
            } else {
                // 如果没有额外得分，动画完成
                this.isPlayingScoreAnimation = false;
            }
        });
    }

    /**
     * 播放额外得分动画
     */
    private playBonusScoreAnimation(): void {
        // 显示额外得分节点
        this.bonusScoreNode.active = true;
        this.bonusScoreLabel.string = `+${this.bonusScore}`;
        
        // 播放额外得分音效
        if (this.bonusAudio) {
            this.bonusAudio.play();
        }

        // 额外得分动画：更炫酷的弹出效果
        const tweenInstance = tween(this.bonusScoreNode)
            .set({ scale: new Vec3(0.3, 0.3, 1), position: new Vec3(140, -333, 0) })
            .to(0.6, { 
                scale: new Vec3(1.5, 1.5, 1) 
            }, { 
                easing: 'elasticOut' 
            })
            .to(0.3, { 
                scale: new Vec3(1.2, 1.2, 1) 
            }, { 
                easing: 'sineOut' 
            })
            .delay(1) // 停留1秒
            .call(() => {
                // 开始移动到总分位置的动画
                this.moveBonusToTotal();
            })
            .start();

        this.currentTweens.push(tweenInstance);

        // 添加闪烁效果
        this.playBonusFlashAnimation();
    }

    /**
     * 播放额外得分的闪烁动画
     */
    private playBonusFlashAnimation(): void {
        const bonusUiOpacity = this.bonusScoreNode.getComponent(UIOpacity);
        if (bonusUiOpacity) {
            const tweenInstance = tween(bonusUiOpacity)
                .repeat(6,
                    tween()
                        .to(0.1, { opacity: 150 }, { easing: 'sineInOut' })
                        .to(0.1, { opacity: 255 }, { easing: 'sineInOut' })
                )
                .start();
            this.currentTweens.push(tweenInstance);
        }
    }

    /**
     * 移动额外得分到总分位置
     */
    private moveBonusToTotal(): void {
        // 计算总分标签的世界坐标位置
        const worldPos = this.totalScoreLabel.node.worldPosition;
        
        // 额外得分移动到总分位置
        const tweenInstance = tween(this.bonusScoreNode)
            .to(1.0, { 
                worldPosition: new Vec3(worldPos.x, worldPos.y, worldPos.z),
                scale: new Vec3(0.4, 0.4, 1)
            }, { 
                easing: 'backIn' 
            })
            .call(() => {
                // 动画完成后更新总分
                this.addBonusToTotalScore();
            })
            .start();

        this.currentTweens.push(tweenInstance);
    }

    /**
     * 将额外得分加入到总分
     */
    private addBonusToTotalScore(): void {
        // 隐藏额外得分节点
        this.bonusScoreNode.active = false;
        
        // 播放总分更新音效
        if (this.bonusAudio) {
            this.bonusAudio.play();
        }
        
        // 更新总分（加上额外分）
        const oldTotal = this.totalScore;
        this.totalScore += this.bonusScore;
        
        // 总分数字滚动动画（更炫酷的效果）
        this.animateBonusTotalScore(oldTotal, this.totalScore);
    }

    /**
     * 总分数字滚动动画（用于额外得分）
     */
    private animateBonusTotalScore(from: number, to: number): void {
        const duration = 1.0; // 动画持续时间
        const startTime = Date.now();
        
        // 清除之前的定时器
        if (this.scoreAnimationTimer) {
            clearTimeout(this.scoreAnimationTimer);
            this.scoreAnimationTimer = 0;
        }
        
        const updateScore = () => {
            const currentTime = Date.now();
            const elapsed = currentTime - startTime;
            const progress = Math.min(elapsed / (duration * 1000), 1);
            
            // 使用弹性缓动函数让动画更炫酷
            const easeOutElastic = this.easeOutElastic(progress);
            const currentScore = Math.floor(from + (to - from) * easeOutElastic);
            
            this.updateTotalScoreDisplay(currentScore);
            
            if (progress < 1) {
                this.scoreAnimationTimer = setTimeout(updateScore, 16); // 约60帧
            } else {
                this.updateTotalScoreDisplay(to); // 确保最终值准确
                // 额外得分动画完成
                this.isPlayingScoreAnimation = false;
            }
        };
        
        updateScore();
        
        // 总分标签更炫酷的缩放动画
        const tweenInstance = tween(this.totalScoreLabel.node)
            .to(0.2, { scale: new Vec3(1.8, 1.8, 1) }, { easing: 'backOut' })
            .to(0.3, { scale: new Vec3(1.2, 1.2, 1) }, { easing: 'elasticOut' })
            .to(0.2, { scale: new Vec3(1, 1, 1) }, { easing: 'sineIn' })
            .start();

        this.currentTweens.push(tweenInstance);
    }

    /**
     * 弹性缓动函数
     */
    private easeOutElastic(x: number): number {
        const c4 = (2 * Math.PI) / 3;
        return x === 0 ? 0 : x === 1 ? 1 : Math.pow(2, -10 * x) * Math.sin((x * 10 - 0.75) * c4) + 1;
    }

    /**
     * 总分数字滚动动画
     */
    private animateTotalScore(from: number, to: number, onComplete?: () => void): void {
        const duration = 1.0; // 动画持续时间
        const startTime = Date.now();
        
        // 清除之前的定时器
        if (this.scoreAnimationTimer) {
            clearTimeout(this.scoreAnimationTimer);
            this.scoreAnimationTimer = 0;
        }
        
        const updateScore = () => {
            const currentTime = Date.now();
            const elapsed = currentTime - startTime;
            const progress = Math.min(elapsed / (duration * 1000), 1);
            
            // 使用缓动函数让动画更自然
            const easeOutQuart = 1 - Math.pow(1 - progress, 4);
            const currentScore = Math.floor(from + (to - from) * easeOutQuart);
            
            this.updateTotalScoreDisplay(currentScore);
            
            if (progress < 1) {
                this.scoreAnimationTimer = setTimeout(updateScore, 16); // 约60帧
            } else {
                this.updateTotalScoreDisplay(to); // 确保最终值准确
                if (onComplete) {
                    onComplete();
                }
            }
        };
        
        updateScore();
        
        // 总分标签缩放动画
        const tweenInstance = tween(this.totalScoreLabel.node)
            .to(0.15, { scale: new Vec3(1.3, 1.3, 1) }, { easing: 'sineOut' })
            .to(0.15, { scale: new Vec3(1, 1, 1) }, { easing: 'sineIn' })
            .start();

        this.currentTweens.push(tweenInstance);
    }

    /**
     * 更新总分显示
     */
    private updateTotalScoreDisplay(score?: number): void {
        if (score !== undefined) {
            this.totalScoreLabel.string = `${score}`;
        } else {
            this.totalScoreLabel.string = `${this.totalScore}`;
        }
    }

    /**
     * 显示骰子开奖动画 - 现在只用于特殊情况
     */
    private showDiceAnimation(): void {
        // 为每个骰子添加弹出动画
        this.diceDataArray.forEach((dice, index) => {
            // 延迟逐个显示骰子，增加动画层次感
            setTimeout(() => {
                this.playSingleDiceAnimation(dice);
            }, index * 150);
        });
    }

    /**
     * 播放单个骰子的动画效果 - 保留但不再在开盖时使用
     */
    private playSingleDiceAnimation(dice: DiceData): void {
        // 透明度动画 - 使用UIOpacity组件
        if (dice.uiOpacity) {
            const tweenInstance = tween(dice.uiOpacity)
                .set({ opacity: 0 })
                .to(0.3, { opacity: 255 }, { easing: 'sineOut' })
                .start();
            this.currentTweens.push(tweenInstance);
        }

        // 缩放动画
        const scaleTween = tween(dice.node)
            .set({ scale: new Vec3(0.5, 0.5, 1) })
            .to(0.3, { scale: new Vec3(1.2, 1.2, 1) }, { easing: 'backOut' })
            .to(0.15, { scale: new Vec3(1, 1, 1) }, { easing: 'sineOut' })
            .start();
        this.currentTweens.push(scaleTween);

        // 旋转动画 - 使用四元数
        const rotationTween = tween(dice.node)
            .set({ rotation: Quat.fromEuler(new Quat(), 0, 0, randomRangeInt(-180, 180)) })
            .to(0.4, { rotation: Quat.IDENTITY }, { easing: 'elasticOut' })
            .start();
        this.currentTweens.push(rotationTween);
    }

    /**
     * 显示结果和总和 - 使用UIOpacity组件
     */
    private showResult(): void {
        const diceValues = this.diceDataArray.map(dice => dice.value);
        const total = diceValues.reduce((sum, value) => sum + value, 0);
        
        // 基础结果显示
        let resultText = `骰子结果: ${diceValues.join(', ')} | 总和: ${total}`;
        
        // 如果三个点数相同，在结果显示中添加提示
        if (this.isThreeOfAKind) {
            resultText += ` | 三个${diceValues[0]}点！`;
        }
        
        this.resultLabel.string = resultText;

        // 结果标签动画 - 使用UIOpacity组件
        if (this.resultUiOpacity) {
            const tweenInstance = tween(this.resultUiOpacity)
                .set({ opacity: 0 })
                .to(0.3, { opacity: 255 }, { easing: 'linear' })
                .start();
            this.currentTweens.push(tweenInstance);
        }

        const labelTween = tween(this.resultLabel.node)
            .set({ scale: new Vec3(0.8, 0.8, 1) })
            .to(0.3, { scale: new Vec3(1, 1, 1) }, { easing: 'backOut' })
            .start();
        this.currentTweens.push(labelTween);
    }

    /**
     * 强制立即关闭盖子（用于特殊情况）
     */
    public forceCloseLid(): void {
        this.closeCupLid(true);
    }

    /**
     * 获取盖子当前状态
     */
    public isLidOpen(): boolean {
        const currentPos = this.cupLidNode.position;
        const distance = Vec3.distance(currentPos, this.originalLidPosition);
        return distance > 10; // 如果距离原始位置较远，则认为盖子打开
    }

    /**
     * 设置总分（用于初始化或重置）
     */
    public setTotalScore(score: number): void {
        this.totalScore = score;
        this.updateTotalScoreDisplay();
    }

    /**
     * 获取当前总分
     */
    public getTotalScore(): number {
        return this.totalScore;
    }

    /**
     * 组件销毁时清理资源
     */
    protected onDestroy(): void {
        this.stopAllAnimations();
    }
}